﻿//// Licensed to the .NET Foundation under one or more agreements.
//// The .NET Foundation licenses this file to you under the MIT license.

//using System.Collections;
//using System.Linq;

//using Humanizer.Localisation;

//using Microsoft.AspNetCore.Html;
//using Microsoft.AspNetCore.Http;
//using Microsoft.AspNetCore.Mvc.ModelBinding;
//using Microsoft.AspNetCore.Mvc.Rendering;
//using Microsoft.AspNetCore.Mvc.ViewEngines;
//using Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers;
//using Microsoft.Extensions.DependencyInjection;

//namespace WXWorkSvc.Common.TagHelpers;

//internal sealed class TemplateRenderer
//{
//    private const string DisplayTemplateViewPath = "DisplayTemplates";
//    private const string EditorTemplateViewPath = "EditorTemplates";
//    public const string IEnumerableOfIFormFileName = "IEnumerable`" + nameof(IFormFile);

//    private static readonly Dictionary<string, Func<IHtmlHelper, IHtmlContent>> _defaultDisplayActions =
//        new Dictionary<string, Func<IHtmlHelper, IHtmlContent>>(StringComparer.OrdinalIgnoreCase)
//        {
//                //{ "Collection", DefaultDisplayTemplates.CollectionTemplate },
//                //{ "EmailAddress", DefaultDisplayTemplates.EmailAddressTemplate },
//                //{ "HiddenInput", DefaultDisplayTemplates.HiddenInputTemplate },
//                //{ "Html", DefaultDisplayTemplates.HtmlTemplate },
//                //{ "Text", DefaultDisplayTemplates.StringTemplate },
//                //{ "Url", DefaultDisplayTemplates.UrlTemplate },
//                //{ typeof(bool).Name, DefaultDisplayTemplates.BooleanTemplate },
//                //{ typeof(decimal).Name, DefaultDisplayTemplates.DecimalTemplate },
//                //{ typeof(string).Name, DefaultDisplayTemplates.StringTemplate },
//                //{ typeof(object).Name, DefaultDisplayTemplates.ObjectTemplate },
//        };

//    private static readonly Dictionary<string, Func<IHtmlHelper, IHtmlContent>> _defaultEditorActions =
//        new Dictionary<string, Func<IHtmlHelper, IHtmlContent>>(StringComparer.OrdinalIgnoreCase)
//        {
//        //        { "Collection", DefaultEditorTemplates.CollectionTemplate },
//        //        { "EmailAddress", DefaultEditorTemplates.EmailAddressInputTemplate },
//        //        { "HiddenInput", DefaultEditorTemplates.HiddenInputTemplate },
//        //        { "MultilineText", DefaultEditorTemplates.MultilineTemplate },
//        //        { "Password", DefaultEditorTemplates.PasswordTemplate },
//        //        { "PhoneNumber", DefaultEditorTemplates.PhoneNumberInputTemplate },
//        //        { "Text", DefaultEditorTemplates.StringTemplate },
//        //        { "Url", DefaultEditorTemplates.UrlInputTemplate },
//        //        { "Date", DefaultEditorTemplates.DateInputTemplate },
//        //        { "DateTime", DefaultEditorTemplates.DateTimeLocalInputTemplate },
//        //        { "DateTime-local", DefaultEditorTemplates.DateTimeLocalInputTemplate },
//        //        { nameof(DateTimeOffset), DefaultEditorTemplates.DateTimeOffsetTemplate },
//        //        { "Time", DefaultEditorTemplates.TimeInputTemplate },
//        //        { "Month", DefaultEditorTemplates.MonthInputTemplate },
//        //        { "Week", DefaultEditorTemplates.WeekInputTemplate },
//        //        { typeof(byte).Name, DefaultEditorTemplates.NumberInputTemplate },
//        //        { typeof(sbyte).Name, DefaultEditorTemplates.NumberInputTemplate },
//        //        { typeof(short).Name, DefaultEditorTemplates.NumberInputTemplate },
//        //        { typeof(ushort).Name, DefaultEditorTemplates.NumberInputTemplate },
//        //        { typeof(int).Name, DefaultEditorTemplates.NumberInputTemplate },
//        //        { typeof(uint).Name, DefaultEditorTemplates.NumberInputTemplate },
//        //        { typeof(long).Name, DefaultEditorTemplates.NumberInputTemplate },
//        //        { typeof(ulong).Name, DefaultEditorTemplates.NumberInputTemplate },
//        //        { typeof(bool).Name, DefaultEditorTemplates.BooleanTemplate },
//        //        { typeof(decimal).Name, DefaultEditorTemplates.DecimalTemplate },
//        //        { typeof(string).Name, DefaultEditorTemplates.StringTemplate },
//        //        { typeof(object).Name, DefaultEditorTemplates.ObjectTemplate },
//        //        { typeof(IFormFile).Name, DefaultEditorTemplates.FileInputTemplate },
//        //        { IEnumerableOfIFormFileName, DefaultEditorTemplates.FileCollectionInputTemplate },
//        };

//    private readonly IViewEngine _viewEngine;
//    private readonly IViewBufferScope _bufferScope;
//    private readonly ViewContext _viewContext;
//    private readonly ViewDataDictionary _viewData;
//    private readonly string _templateName;
//    private readonly bool _readOnly;

//    public TemplateRenderer(
//        IViewEngine viewEngine,
//        IViewBufferScope bufferScope,
//        ViewContext viewContext,
//        ViewDataDictionary viewData,
//        string templateName,
//        bool readOnly)
//    {
//        ArgumentNullException.ThrowIfNull(viewEngine);
//        ArgumentNullException.ThrowIfNull(bufferScope);
//        ArgumentNullException.ThrowIfNull(viewContext);
//        ArgumentNullException.ThrowIfNull(viewData);

//        _viewEngine = viewEngine;
//        _bufferScope = bufferScope;
//        _viewContext = viewContext;
//        _viewData = viewData;
//        _templateName = templateName;
//        _readOnly = readOnly;
//    }

//    public IHtmlContent Render()
//    {
//        var defaultActions = GetDefaultActions();
//        var modeViewPath = _readOnly ? DisplayTemplateViewPath : EditorTemplateViewPath;

//        //foreach (var viewName in GetViewNames())
//        //{
//        //    var viewEngineResult = _viewEngine.GetView(_viewContext.ExecutingFilePath, viewName, isMainPage: false);
//        //    if (!viewEngineResult.Success)
//        //    {
//        //        var fullViewName = modeViewPath + "/" + viewName;
//        //        viewEngineResult = _viewEngine.FindView(_viewContext, fullViewName, isMainPage: false);
//        //    }

//        //    if (viewEngineResult.Success)
//        //    {
//        //        var viewBuffer = new ViewBuffer(_bufferScope, viewName, ViewBuffer.PartialViewPageSize);
//        //        using (var writer = new ViewBufferTextWriter(viewBuffer, _viewContext.Writer.Encoding))
//        //        {
//        //            // Forcing synchronous behavior so users don't have to await templates.
//        //            var view = viewEngineResult.View;
//        //            using (view as IDisposable)
//        //            {
//        //                var viewContext = new ViewContext(_viewContext, viewEngineResult.View, _viewData, writer);
//        //                var renderTask = viewEngineResult.View.RenderAsync(viewContext);
//        //                renderTask.GetAwaiter().GetResult();
//        //                return viewBuffer;
//        //            }
//        //        }
//        //    }

//        //    if (defaultActions.TryGetValue(viewName, out var defaultAction))
//        //    {
//        //        return defaultAction(MakeHtmlHelper(_viewContext, _viewData));
//        //    }
//        //}

//        throw new InvalidOperationException("NoTemp");
//            //Resources.FormatTemplateHelpers_NoTemplate(_viewData.ModelExplorer.ModelType.FullName));
//    }

//    private Dictionary<string, Func<IHtmlHelper, IHtmlContent>> GetDefaultActions()
//    {
//        return _readOnly ? _defaultDisplayActions : _defaultEditorActions;
//    }

//    private IEnumerable<string> GetViewNames()
//    {
//        var metadata = _viewData.ModelMetadata;
//        var templateHints = new[]
//        {
//                _templateName,
//                metadata.TemplateHint,
//                metadata.DataTypeName
//            };

//        foreach (var templateHint in templateHints.Where(s => !string.IsNullOrEmpty(s)))
//        {
//            yield return templateHint;
//        }

//        // We don't want to search for Nullable<T>, we want to search for T (which should handle both T and
//        // Nullable<T>).
//        var fieldType = metadata.UnderlyingOrModelType;
//        foreach (var typeName in GetTypeNames(metadata, fieldType))
//        {
//            yield return typeName;
//        }
//    }

//    public static IEnumerable<string> GetTypeNames(ModelMetadata modelMetadata, Type fieldType)
//    {
//        // Not returning type name here for IEnumerable<IFormFile> since we will be returning
//        // a more specific name, IEnumerableOfIFormFileName.

//        if (typeof(IEnumerable<IFormFile>) != fieldType)
//        {
//            yield return fieldType.Name;
//        }

//        if (fieldType == typeof(string))
//        {
//            // Nothing more to provide
//            yield break;
//        }
//        else if (!modelMetadata.IsComplexType)
//        {
//            // IsEnum is false for the Enum class itself
//            if (fieldType.IsEnum)
//            {
//                // Same as fieldType.BaseType.Name in this case
//                yield return "Enum";
//            }
//            else if (fieldType == typeof(DateTimeOffset))
//            {
//                yield return "DateTime";
//            }

//            yield return "String";
//            yield break;
//        }
//        else if (!fieldType.IsInterface)
//        {
//            var type = fieldType;
//            while (true)
//            {
//                type = type.BaseType;
//                if (type == null || type == typeof(object))
//                {
//                    break;
//                }

//                yield return type.Name;
//            }
//        }

//        if (typeof(IEnumerable).IsAssignableFrom(fieldType))
//        {
//            if (typeof(IEnumerable<IFormFile>).IsAssignableFrom(fieldType))
//            {
//                yield return IEnumerableOfIFormFileName;

//                // Specific name has already been returned, now return the generic name.
//                if (typeof(IEnumerable<IFormFile>) == fieldType)
//                {
//                    yield return fieldType.Name;
//                }
//            }

//            yield return "Collection";
//        }
//        else if (typeof(IFormFile) != fieldType && typeof(IFormFile).IsAssignableFrom(fieldType))
//        {
//            yield return nameof(IFormFile);
//        }

//        yield return "Object";
//    }

//    private static IHtmlHelper MakeHtmlHelper(ViewContext viewContext, ViewDataDictionary viewData)
//    {
//        var newHelper = viewContext.HttpContext.RequestServices.GetRequiredService<IHtmlHelper>();

//        if (newHelper is IViewContextAware contextable)
//        {
//            var newViewContext = new ViewContext(viewContext, viewContext.View, viewData, viewContext.Writer);
//            contextable.Contextualize(newViewContext);
//        }

//        return newHelper;
//    }
//}